import { BlockOutlined, CopyOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import { useMount } from 'ahooks'
import { Form, Input, Modal, Select, Space } from 'antd'
import { uniq, debounce } from 'lodash'
import { useState } from 'react'
import './app.less'

type Cookie = chrome.cookies.Cookie & {
}

export default function Cookies() {
  const [form] = Form.useForm()
  const [domain, setDomain] = useState<string[]>([])
  const [filteredCookies, setFilteredCookies] = useState<Cookie[]>([])

  useMount(() => {
    // 检索扩展程序拥有主机权限的网域的 Cookie
    chrome.cookies.getAll({}, (cookies) => {
      console.log(cookies)
      setDomain(uniq(cookies.map(c => c.domain)))
      const selectedDomain = localStorage.getItem('cookies-selected-domain')
      if (selectedDomain) setFormValue(selectedDomain)
    })

    // 列出所有现有的 Cookie 存储区
    chrome.cookies.getAllCookieStores((cookieStores) => {
      console.log('cookieStores', cookieStores);
    })
  })

  async function copy(name: number) {
    const { cookies } = form.getFieldsValue()
    await navigator.clipboard.writeText(JSON.stringify(cookies[name]))
  }

  function isChange(name: string, value: string, path: string) {
    for (const c of filteredCookies) {
      if (c.name === name) {
        return c.value !== value || c.path !== path
      }
    }
    return true
  }

  function handleChange() {
    const { cookies } = form.getFieldsValue()
    const selectedDomain = localStorage.getItem('cookies-selected-domain')
    cookies.forEach(({ domain, name, value, path, httpOnly, secure, sameSite }: Cookie) => {
      if (isChange(name, value, path)) {
        // https://developer.chrome.com/docs/extensions/reference/api/cookies
        const details = {
          // 要与 Cookie 设置相关联的请求 URI。此值可能会影响所创建 Cookie 的默认网域和路径值。如果清单文件中未指定此网址的主机权限，则 API 调用将失败。
          url:`https://pre-a.ele.me`, // TODO
          domain: (domain || selectedDomain) as string,
          name,
          value,
          path,
          secure,
          httpOnly,
          sameSite: sameSite as chrome.cookies.SameSiteStatus
        };
        console.log('details', details);
        chrome.cookies.set(details, (e) => {
          console.log('cb',e);
        });
      }
    })
  }

  function setFormValue(value: string) {
    chrome.cookies.getAll({ domain: value }, (cookies) => {
      console.log(value, cookies);
      localStorage.setItem('cookies-selected-domain', value)
      const filtered = cookies.filter(c => c.name !== '')
      form.setFieldValue('cookies', filtered)
      setFilteredCookies(filtered)
    })
  }

  function removeCookie(index: number) {
    if (filteredCookies[index]) {
      const name = filteredCookies[index].name
      const selectedDomain = localStorage.getItem('cookies-selected-domain')
      chrome.cookies.remove({ name, url: `https://${selectedDomain}` })
    }
  }

  const [isModalOpen, setIsModalOpen] = useState(false)
  const [textarea, setTextarea] = useState('')

  const handleOk = () => {
    const item = JSON.parse(textarea)
    const { cookies } = form.getFieldsValue()
    form.setFieldsValue({ cookies: [...cookies, item as Cookie] })
    setIsModalOpen(false)
    handleChange()
  }
  
  return (
    <div className="cookies">
      <div className="filter">
        <span className="prefix">Domain</span>
        <Select
          showSearch
          style={{ width: 200 }}
          defaultValue={localStorage.getItem('cookies-selected-domain')}
          placeholder="Select a domain"
          filterOption={(input, option) =>
            (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
          }
          options={domain.map(d => ({ value: d, label: d }))}
          onChange={setFormValue}
        />
      </div>
      <Form
        form={form}
        autoComplete="off"
        onChange={debounce(handleChange, 300)}
      >
        <Space className="form-list-head">
          <div className="form-item-name">Name</div>
          <div className="form-item-value">Value</div>
          <div className="form-item-expires">Expires/Max-Age</div>
          <div className="form-item-samesite">SameSite</div>
          <div className="form-item-secure">Secure</div>
          <div className="form-item-path">Path</div>
        </Space>
        <Form.List name="cookies">
          {(fields, { add, remove }) => (
            <>
              {fields.map((field) => (
                <Space key={field.key} className="form-item-wrapper">
                  <Form.Item name={[field.name, 'name']} className="form-item-name allow-clear-hover">
                    <Input allowClear placeholder="Name" />
                  </Form.Item>
                  <Form.Item name={[field.name, 'value']} className="form-item-value allow-clear-hover">
                    <Input allowClear placeholder="Value" />
                  </Form.Item>
                  <Form.Item name={[field.name, 'expires']} className="form-item-expires allow-clear-hover">
                    <Input allowClear placeholder="Expires/Max-Age" />
                  </Form.Item>
                  <Form.Item name={[field.name, 'sameSite']} className="form-item-sameSite allow-clear-hover">
                    <Input allowClear />
                  </Form.Item>
                  <Form.Item name={[field.name, 'secure']} className="form-item-secure allow-clear-hover">
                    <Input allowClear placeholder="Secure" />
                  </Form.Item>
                  <Form.Item name={[field.name, 'path']} className="form-item-path allow-clear-hover">
                    <Input allowClear placeholder="Path" />
                  </Form.Item>
                  <Form.Item>
                    <Space>
                      <CopyOutlined onClick={() => copy(field.name)} />
                      <MinusCircleOutlined onClick={() => { remove(field.name); removeCookie(field.name) }} />
                    </Space>
                  </Form.Item>
                </Space>
              ))}
              <div>
                <Space>
                  <span onClick={() => add({ path: '/' })}><PlusOutlined /> Add Cookies</span>
                  <span onClick={() => setIsModalOpen(true)}><BlockOutlined /> Import Cookies</span>
                </Space>
              </div>
            </>
          )}
        </Form.List>
      </Form>
      <Modal
        title="Import Cookies"
        closable={{ 'aria-label': 'Custom Close Button' }}
        open={isModalOpen}
        onOk={handleOk}
        onCancel={() => setIsModalOpen(false)}
      >
        <Input.TextArea rows={8} value={textarea} onChange={e => setTextarea(e.target.value)} />
      </Modal>
    </div>
  )
}

/*
SameSite Cookie 是一种安全机制，用于防止跨站请求伪造攻击（CSRF）。它通过限制浏览器何时可以在跨站请求中发送 cookie，从而增强安全性。
Strict 模式：cookie 只会在来自同一站点的请求中发送，任何跨站请求（比如第三方网站的链接或表单提交）都不会发送这些 cookie。这种设置提供了最高级别的安全性。
Lax 模式：cookie 在同一站点请求和某些跨站请求（如通过 GET 方法导航到目标网站）中发送，但不包括其他类型的跨站请求（如 POST）。这是默认模式，提供了安全性和可用性之间的平衡。
None 模式：cookie 在所有请求中发送，不管是不是跨站请求。在这种模式下使用时，cookie 必须标记为 Secure，确保只有在 HTTPS 连接中传输。

在 HTTP Cookie 的 sameSite 属性中，unspecified 通常意味着未明确设置 sameSite，而 no_restriction 对应于 None。
unspecified = 未指定
no_restriction = 无限制
unspecified = 默认设置：如果未设置 sameSite，浏览器通常按照默认的 Lax 处理。
None = 无限制，自由传递：可以在任何请求中发送，但需要加锁（Secure）。
*/